# Algorithm: sensor training
# input: 3个特征值
# output: 1个加权和分数
# step:
# 1. 初始化权重w和偏置b为0
# 2.
# ...
# example:
from predict import predict_by_weighted_sum_classification
def sensor_training_regression(x_train, y_train,name="sensor_model")->(list,float):
    """
        感知机训练函数
        input: 3个特征值
        output: 1个加权和分数
    """
    # result:
    weights = [0.0001, 0.0001, 0.0001]
    bias = 0
    # 初始化权重w和偏置b为0
    learning_rate = 0.0001
    for epoch in range(10):
        for i in range(len(x_train)):
            # 预测(根据当前权重和偏置计算加权和做为预测值)并保留预测值
            # 计算加权和
            prediction = predict_by_weighted_sum(x_train[i], weights, bias)
            # 获取当前样本的真实值
            true_label = y_train[i]
            # 计算偏差
            error = true_label - prediction
            # 更新权重和偏置
            for j in range(len(weights)):
                weights[j] += learning_rate * error * x_train[i][j]
            bias += learning_rate * error
             # 打印当前迭代的权重和偏置
            print(f"Epoch {epoch}, Sample {i}: Weights = {weights}, Bias = {bias}")
            # 同时导出为一个模型文件，仅保留权重、偏置。并安装命名参数命名。
            with open(r"./"+name+".txt", "w",encoding="utf-8") as f:
                # 作为字符串写入文件
                for j in range(len(weights)):
                    f.write(f"{float(weights[j]):.6f} ")
                bias_str = f"{float(bias):.6f}"
                f.write(f"{bias_str}\n")
    return weights, bias

def sensor_training_classification(x_train, y_train,name="sensor_model")->(list,float):
    """
        感知机训练函数(分类)
        input: 3个特征值
        output: 1个加权和分数
    """
    # result:
    weights = [0.001, 0.001, 0.001]
    bias = 0
    # 初始化权重w和偏置b为0
    learning_rate = 0.0001
    for epoch in range(10):
        for i in range(len(x_train)):
            # 预测(根据当前权重和偏置计算加权和做为预测值)并保留预测值
            # 计算加权和
            prediction = predict_by_weighted_sum_classification(x_train[i], weights, bias)
            # 获取当前样本的真实值
            true_label = y_train[i]
            # 计算偏差
            error = true_label - prediction
            # 更新权重和偏置
            for j in range(len(weights)):
                weights[j] += learning_rate * error * x_train[i][j]
            bias += learning_rate * error
             # 打印当前迭代的权重和偏置
            print(f"Epoch {epoch}, Sample {i}: Weights = {weights}, Bias = {bias}")
            # 同时导出为一个模型文件，仅保留权重、偏置。并安装命名参数命名。
            with open(r"./"+name+".txt", "w",encoding="utf-8") as f:
                # 作为字符串写入文件
                for j in range(len(weights)):
                    f.write(f"{float(weights[j]):.6f} ")
                bias_str = f"{float(bias):.6f}"
                f.write(f"{bias_str}\n")
    return weights, bias


# 读取模型参数的函数
def read_model_params(path="sensor_model.txt")->(list,float):
    """
        读取模型参数函数
        input: 无
        output: 权重列表和偏置
    """
    with open(path, "r") as f:
        # 读取第一行的前三位作为权重
        line = f.readline()
        weights = [float(line.split()[i]) for i in range(3)]
        # 读取第一行的第四位作为偏置
        bias = float(line.split()[3])
    return weights, bias